package com.zjlab.sandtable.bean;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author xue
 * @create 2022-11-07 14:24
 */
@Slf4j
public abstract class Info {


    /**
     * 返回各自的类型指定
     *
     * @return
     */
    public abstract Integer getInfoType();

    /**
     * 编码器
     *
     * @param byteBuf
     * @return
     */
    public ByteBuf encoding(ByteBuf byteBuf) {
        byteBuf.writeByte(Info.MAGIC);
        JSONObject jsonObject = JSONUtil.parseObj(this);
        if (jsonObject.isEmpty()) {
            byteBuf.writeShort(Info.FRAME_HEADER);
            byteBuf.writeShort(getInfoType());
        } else {
            byte[] bytes = jsonObject.toString().getBytes(StandardCharsets.UTF_8);
            byteBuf.writeShort(bytes.length + Info.FRAME_HEADER);
            byteBuf.writeShort(getInfoType());
            byteBuf.writeBytes(bytes);
        }
        return byteBuf;
    }


    /**
     * 解码器
     *
     * @param content
     * @return
     */
    public Info decoding(ByteBuf content) {
        byte[] date = new byte[content.readableBytes()];
        content.readBytes(date);
        return JSONUtil.toBean(new String(date, StandardCharsets.UTF_8), this.getClass());
    }


    public static final byte FRAME_HEADER = 5;
    public static final byte MAGIC = 0x66;


    public static final Integer TURN_OFF_CAR_LIGHT = 3;
    public static final Integer PROJECTION = 4;
    public static final Integer NDN_LAMP = 5;
    public static final Integer MF_MODEL = 6;
    public static final Integer MF_STATUS = 7;
    public static final Integer MF_LOGS = 8;
    public static final Integer COINS_MAKE = 9;
    public static final Integer COINS_MAKE_STATUS = 10;
    public static final Integer WEB_SITE_ADDRESS = 11;
    public static final Integer AREA_BASE_INFO = 16;

    public static final Integer SCREEN_SHOW_INFO = 17;
    public static final Integer CAR_SPEED_REQUEST_INFO = 18;
    public static final Integer CAR_SPEED_INFO = 19;
    public static final Integer CAR_SPEED_SET_INFO = 20;
    public static final Integer MODE_INFO = 21;
    public static final Integer MEDIA_INFO = 22;

    private static final Map<Integer, Class<? extends Info>> infoClasses = new ConcurrentHashMap<>();

    static {
        infoClasses.put(CAR_SPEED_INFO, CarSpeedInfo.class);
        infoClasses.put(COINS_MAKE_STATUS, CoinsMakeStatusInfo.class);
        infoClasses.put(MF_LOGS, MfLogsInfo.class);
    }

    /**
     * 根据消息类型字节，获得对应的消息 class
     *
     * @param infoType 消息类型字节
     * @return 消息 class
     */
    public static Class<? extends Info> getInfoClass(Integer infoType) {
        return infoClasses.get(infoType);
    }


}
